package com.pzl.library;

import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.OvershootInterpolator;
import android.widget.AbsListView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

/**
 * Created by Administrator on 2016-04-13.
 * 不要paddingleft,paddingright,paddingtop,paddingbottom
 * 左右padding通过设置paddingStartEnd,上下pading通过设置初始高度NormalHeight
 * 沉浸式状态栏的高度设margintop
 * 强制分发event
 */
public class ExpandableActionBar extends RelativeLayout implements View.OnClickListener {
    private final String TAG = "ExpandableActionBar";
    /**
     * 左按钮
     */
    private ImageView mIvLeft;
    /**
     * 右按钮
     */
    private ImageView mIvRight;
    /**
     * 主标题
     */
    private TextView mTvTitleMain;
    /**
     * 副标题
     */
    private TextView mTvTitleSub;
    /**
     * 主标题最小字号
     */
    private int mMainTitleMinPx;
    /**
     * 主标题最大字号
     */
    private int mMainTitleMaxPx;
    /**
     * 主标题字号改变量
     */
    private int mDeltaSize;


    private int mLeftBtnResId;
    private int mRightBtnResId;
    /**
     * 按钮左右margin间距
     */
    private float mPaddingStartEnd;
    /**
     * 缩进时候的高度，mNormalHeight = contentHeight（容器ll的高度,垂直居中；title tv 初始化的高度）
     */
    private final float mNormalHeight;
    /**
     * 拉伸开来时的总高度（不包括动画高度）
     */
    private final float mExpandHeight;
    /**
     * 按钮宽度
     */
    private float mBtnWidth;
    /**
     * 按钮高度
     */
    private float mBtnHeight;
    /**
     * 正常ActionBar容器，里面是按钮
     */
    private RelativeLayout mRelativeLayout;
    /**
     * 主标题，副标题容器
     */
    private LinearLayout mLinearLayoutTitle;
    /**
     * 是否拦截事件
     */
    private boolean mShouldIntercept = false;
    /**
     * 当前拉伸的长度
     */
    private float mCurrentExpand = 0;
    /**
     * 是否展开的状态
     */
    private boolean mIsExtend = false;
    /**
     * 动画变换的长度
     */
    private float mAnimationHeight;

    private float mOldY, mNewY;
    /**
     * 绑定的listview
     */
    private View mBindView;
    /**
     * 绑定listview的外部监听
     */
    private BindListener mBindListener;
    private ValueAnimator mValueAnimator;
    private int mAnimDuration = 200;
    /**
     * 缩放的背景图片
     */
    private ScaleImageView mIvBg;
    /**
     * 不缩放，左边靠齐
     */
    public static final int TYPE_START = 0;
    /**
     * 不缩放，右边靠齐
     */
    public static final int TYPE_END = 1;
    /**
     * 不缩放，横向居中
     */
    public static final int TYPE_CENTER = 2;
    /**
     * 填充imageview宽度为基准，等比缩放
     */
    public static final int TYPE_FIX_WIDTH = 3;
    /**
     * 等比缩放填充imageview宽度，以右边为基点缩放
     */
    public static final int TYPE_FIX_WIDTH_AT_END = 4;
    /**
     * 等比缩放填充imageview宽度，以左边为基点缩放
     */
    public static final int TYPE_FIX_WIDTH_AT_START = 5;
    /**
     * 按钮点击回调
     */
    private IOnActionBtnClick mIOnActionBtnClick;

    private int mStatusBarHeight;
    private Context mContext;
    /**
     * 定长模式
     */
    private final int STATIC = 0;
    /**
     * 下拉减速模式
     */
    private final int DYNAMIC = 1;
    /**
     * 下拉阻力系数
     */
    private final float mResistanceCoefficient = 0.3f;
    /**
     * 下拉回弹动画模式
     */
    private int mAnimMode;

    //TODO 下拉回弹做成减速缓冲形式；内置下拉刷新功能
    public ExpandableActionBar(Context context) {
        this(context, null);
    }

    public ExpandableActionBar(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ExpandableActionBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        mContext = context;

        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.ExpandableActionBar);
        mLeftBtnResId = ta.getResourceId(R.styleable.ExpandableActionBar_leftBtn, 0);
        mRightBtnResId = ta.getResourceId(R.styleable.ExpandableActionBar_rightBtn, 0);
        mExpandHeight = ta.getDimension(R.styleable.ExpandableActionBar_expandHeight, 0);
        mNormalHeight = ta.getDimension(R.styleable.ExpandableActionBar_normalHeight, 0);
        mAnimationHeight = ta.getDimension(R.styleable.ExpandableActionBar_animationHeight, 0);
        mBtnWidth = ta.getDimension(R.styleable.ExpandableActionBar_btnWidth, 0);
        mBtnHeight = ta.getDimension(R.styleable.ExpandableActionBar_btnHeight, 0);
        mPaddingStartEnd = ta.getDimension(R.styleable.ExpandableActionBar_paddingStartEnd, 0);
        mAnimMode = ta.getInt(R.styleable.ExpandableActionBar_animMode, 0);
        ta.recycle();

        initView();
        mBindListener = new BindListener();
        mIvLeft.setOnClickListener(this);
        mIvRight.setOnClickListener(this);
    }

    private void initView() {
        mIvBg = new ScaleImageView(mContext);
        mIvLeft = new ImageView(mContext);
        mIvRight = new ImageView(mContext);
        mTvTitleMain = new TextView(mContext);
        mTvTitleSub = new TextView(mContext);
        mRelativeLayout = new RelativeLayout(mContext);
        mLinearLayoutTitle = new LinearLayout(mContext);

        //透明沉浸式状态栏
        mStatusBarHeight = getStatusBarHeight();
        //背景图片
        LayoutParams lp_bgPic = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        lp_bgPic.addRule(RelativeLayout.ALIGN_PARENT_TOP);
        addView(mIvBg, lp_bgPic);
        //右按钮
        LayoutParams lp_IvRight = new LayoutParams((int) mBtnWidth, (int) mBtnHeight);
        lp_IvRight.addRule(RelativeLayout.CENTER_VERTICAL);
        lp_IvRight.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
        mIvRight.setBackgroundResource(mRightBtnResId);
        mRelativeLayout.addView(mIvRight, lp_IvRight);
        //左按钮
        LayoutParams lp_IvLeft = new LayoutParams((int) mBtnWidth, (int) mBtnHeight);
        lp_IvLeft.addRule(RelativeLayout.CENTER_VERTICAL);
        lp_IvLeft.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
        mIvLeft.setBackgroundResource(mLeftBtnResId);
        mRelativeLayout.addView(mIvLeft, lp_IvLeft);
        //正常actionbar容器，正常高度
        LayoutParams lp_rl = new LayoutParams(LayoutParams.MATCH_PARENT, (int) mNormalHeight);
        lp_rl.addRule(RelativeLayout.ALIGN_PARENT_TOP);
        lp_rl.setMargins(0, mStatusBarHeight, 0, 0);
        mRelativeLayout.setPadding((int) mPaddingStartEnd, 0, (int) mPaddingStartEnd, 0);
        addView(mRelativeLayout, lp_rl);
        //初始化正常状态的主标题 textview
        LinearLayout.LayoutParams lp_mainTitle = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        mLinearLayoutTitle.addView(mTvTitleMain, lp_mainTitle);
        //初始化正常状态的副标题 textview
        LinearLayout.LayoutParams lp_subTitle = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        mLinearLayoutTitle.addView(mTvTitleSub, lp_subTitle);
        //初始化正常状态的Title容器LinearLayout
        LayoutParams lp_ll = new LayoutParams(LayoutParams.WRAP_CONTENT, (int) mNormalHeight);
        lp_ll.addRule(RelativeLayout.ALIGN_PARENT_TOP);
        lp_ll.addRule(RelativeLayout.CENTER_HORIZONTAL);
        lp_ll.setMargins(0, mStatusBarHeight, 0, 0);
        mLinearLayoutTitle.setGravity(Gravity.CENTER);
        mLinearLayoutTitle.setOrientation(LinearLayout.VERTICAL);
        addView(mLinearLayoutTitle, lp_ll);


        mTvTitleSub.setVisibility(View.GONE);
        //mLinearLayoutTitle.setBackgroundColor(Color.YELLOW);//for test
        mIvBg.setBackgroundColor(Color.YELLOW);
    }

    /**
     * 设置背景图片
     *
     * @param bitmap
     * @param initType
     */
    public void setBgBitmap(Bitmap bitmap, int initType) {
        mIvBg.setBitmapImage(bitmap, initType);
    }

    /**
     * 设置背景资源
     *
     * @param resId
     * @param initType
     */
    public void setBgResource(int resId, int initType) {
        mIvBg.setResourceImage(resId, initType);
    }

    /**
     * 设置主标题
     *
     * @param text
     * @param minSp
     * @param maxSp
     */
    public void setMainTitle(String text, int minSp, int maxSp) {
        mMainTitleMinPx = sp2px(minSp, mContext);
        mMainTitleMaxPx = sp2px(maxSp, mContext);
        mDeltaSize = mMainTitleMaxPx - mMainTitleMinPx;
        mTvTitleMain.setTextSize(mMainTitleMinPx);
        mTvTitleMain.setText(text);

    }

    /**
     * 设置副标题
     *
     * @param text
     */
    public void setSubTitle(String text, int sp) {
        mTvTitleSub.setTextSize(sp2px(sp, mContext));
        mTvTitleSub.setText(text);
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //被绑定的view
        if (mBindView == null) {
            mBindView = getChildAt(3);
            mBindView.setOnTouchListener(mBindListener);
        }
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        LayoutParams lp_bindView = (LayoutParams) mBindView.getLayoutParams();
        lp_bindView.setMargins(0, mStatusBarHeight + (int) mNormalHeight + (int) mCurrentExpand, 0, 0);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {//TODO 下拉刷新事件处理，点击事件处理
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mOldY = event.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                mNewY = event.getY();
                float dy = mNewY - mOldY;

                if (mOldY != -10000) {//过滤（拦截状态立即生效时候）强制分发ACTION_DOWN的错误数据：downY=-10000
                    expandOp(dy);
                }

                mOldY = mNewY;
                requestLayout();

                if (mCurrentExpand == 0) {
                    mIsExtend = false;
                    if (dy < 0 && mShouldIntercept == false) {
                        event.setAction(MotionEvent.ACTION_DOWN);
                        dispatchTouchEvent(event);//解除listview拦截立即生效（保证它仅调用一次）
                    }
                } else {//TODO 下拉刷新怎么拦截
                    mIsExtend = true;
                }
                break;
            case MotionEvent.ACTION_UP:
                if (mCurrentExpand <= mExpandHeight - mNormalHeight) return true;
                float from = mCurrentExpand;
                if (mValueAnimator != null && mValueAnimator.isRunning() == true) {
                    mValueAnimator.removeAllListeners();
                    mValueAnimator.cancel();
                }
                mValueAnimator = ValueAnimator.ofFloat(from, mExpandHeight - mNormalHeight);
                mValueAnimator.setDuration(mAnimDuration);
                mValueAnimator.setInterpolator(new OvershootInterpolator());
                mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        float newValue = (Float) animation.getAnimatedValue();
                        mCurrentExpand = newValue;
                        ExpandableActionBar.this.onScroll();
                        ExpandableActionBar.this.requestLayout();
                    }
                });
                mValueAnimator.start();
                break;
        }
        return true;
    }

    /**
     * 展开收缩操作
     */
    private void expandOp(float dy) {
        if (mAnimMode == DYNAMIC && mCurrentExpand > mExpandHeight - mNormalHeight && dy > 0) {
            mCurrentExpand += dy * mResistanceCoefficient;
        } else {
            mCurrentExpand += dy;
        }
        if (mCurrentExpand <= 0) {
            mCurrentExpand = 0;
            if (dy < 0) {
                mShouldIntercept = false;
            }
            onScroll();
        } else if (mAnimMode == STATIC && mCurrentExpand >= mExpandHeight + mAnimationHeight - mNormalHeight) {
            mCurrentExpand = mExpandHeight + mAnimationHeight - mNormalHeight;
        } else {//TODO 暂定，按比例尺缩
            onScroll();
        }
    }

    /**
     * 响应逻辑
     */
    protected void onScroll() {
        mIvBg.zoomTo((1 + (mCurrentExpand / (mStatusBarHeight + mNormalHeight))), 0, 0);
        if (mCurrentExpand <= mExpandHeight - mNormalHeight) {
            LayoutParams layoutParams = (LayoutParams) mLinearLayoutTitle.getLayoutParams();
            layoutParams.height = (int) (mNormalHeight + mCurrentExpand);
            float rat = mCurrentExpand / (mExpandHeight - mNormalHeight);
            float curDeltaSize = mDeltaSize * rat;
            mTvTitleMain.setTextSize(mMainTitleMinPx + curDeltaSize);
            mTvTitleSub.setAlpha(rat);
        }
        if (mCurrentExpand <= mTvTitleSub.getHeight()) {
            mTvTitleSub.setVisibility(View.GONE);
        } else {
            mTvTitleSub.setVisibility(View.VISIBLE);
        }
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return mShouldIntercept;
    }

    @Override
    public void onClick(View v) {
        if (mIOnActionBtnClick == null) return;
        if (v == mIvLeft) {
            mIOnActionBtnClick.onLeftClick();
        } else if (v == mIvRight) {
            mIOnActionBtnClick.onRightClick();
        }
    }

    /**
     * BindListener
     */
    class BindListener implements OnTouchListener {
        private final String TAG = "BindListener";
        float oldY, newY;

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    oldY = event.getY();
                    break;
                case MotionEvent.ACTION_MOVE:
                    if (mBindView.getLayoutParams().height != mStatusBarHeight + mNormalHeight) {
                        requestLayout();//最后一次事件监听转移时出现的数据（mCurrentExpand）更新了，而没刷新margin布局的情况
                    }
                    newY = event.getY();
                    float dy = newY - oldY;
                    if (newY > oldY) {
                        Log.i(TAG, "↓");
                        if (isScrollTop((AbsListView) v)) {
                            Log.i(TAG, "事件被上面拦截");
                            mShouldIntercept = true;
                        }
                    } else {
                        Log.i(TAG, "↑");
                    }
                    if (mShouldIntercept) {
                        event.setAction(MotionEvent.ACTION_DOWN);
                        event.setLocation(event.getX(), -10000);//给出指定的错误数据以过滤
                        ExpandableActionBar.this.dispatchTouchEvent(event);////拦截listview的事件立即生效（保证它仅调用一次）
                    }
                    oldY = newY;
                    break;
                case MotionEvent.ACTION_UP:
                    break;
            }
            return mShouldIntercept;
        }


        /**
         * for only one child listview
         *
         * @param listView
         * @return
         */
        public int getScrollY(AbsListView listView) {
            View c = listView.getChildAt(0);
            if (c == null) {
                return 0;
            }
            int firstVisiblePosition = listView.getFirstVisiblePosition();
            int top = c.getTop();
            return -top + firstVisiblePosition * c.getHeight();//TODO item高度不同的时候,headview,footview 的测量
        }

        /**
         * for only one child listview
         * listview是否滚动到顶部
         *
         * @return
         */
        public boolean isScrollTop(AbsListView listView) {//TODO 其它类型view
            View c = listView.getChildAt(0);
            if (c == null) {
                return true;//listview为空，使它也可以展开查看
            }
            if (c.getTop() >= 0 && listView.getFirstVisiblePosition() == 0) {
                return true;
            } else {
                return false;
            }
        }
    }

    private int getStatusBarHeight() {
        int result = 0;
        int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            result = getResources().getDimensionPixelSize(resourceId);
        }
        return result;
    }

    /**
     * 将sp值转换为px值，保证文字大小不变
     */
    public static int sp2px(float spValue, Context context) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (spValue * scale + 0.5f);
    }

    /**
     * 注册按钮点击监听
     *
     * @param lintener
     */
    public void registerActionBtnListener(IOnActionBtnClick lintener) {
        mIOnActionBtnClick = lintener;
    }

    public interface IOnActionBtnClick {
        void onLeftClick();

        void onRightClick();
    }
}
